package com.ccrfid.rmc6.lbservice3.client;

import com.ccrfid.rmc6.appconfig.websocket.MsgEntity;
import com.ccrfid.rmc6.util.JsonUtil;
import org.glassfish.jersey.media.sse.EventOutput;
import org.glassfish.jersey.media.sse.OutboundEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.List;

public class SseClient extends WebClient {
    private static final Logger logger = LoggerFactory.getLogger(SseClient.class);
    private EventOutput eventOutput;

    public SseClient(String clientId, String userAccount, List<String> clientIpAddrs, EventOutput eventOutput) {
        super(clientId, userAccount, clientIpAddrs);
        this.eventOutput = eventOutput;
    }

    public EventOutput getEventOutput() {
        return eventOutput;
    }

    public void setEventOutput(EventOutput eventOutput) {
        this.eventOutput = eventOutput;
    }

    @Override
    public void postMsg(String msgType, String msgContent) throws IOException {
        OutboundEvent.Builder builder = new OutboundEvent.Builder();
        builder.name(msgType);
        builder.mediaType(MediaType.APPLICATION_JSON_TYPE);
        builder.data(msgContent);
        synchronized (eventOutput) {
            this.eventOutput.write(builder.build());
        }
        logger.debug("SSE -- post to client: {}/{}, msgType: {}, msgContent: {}",
                getClientId(), getClientIpAddrs(), msgType, msgContent);
    }

    @Override
    public void postMsg(MsgEntity<?> msgEntity) throws IOException {
        String msgContent = JsonUtil.INSTANCE.writeValueAsString(msgEntity.getContent());
        OutboundEvent.Builder builder = new OutboundEvent.Builder();
        builder.name(msgEntity.getType());
        builder.mediaType(MediaType.APPLICATION_JSON_TYPE);
        builder.data(msgContent);
        synchronized (eventOutput) {
            this.eventOutput.write(builder.build());
        }
        logger.debug("SSE -- post to client: {}/{}, msgType: {}, msgContent: {}",
                getClientId(), getClientIpAddrs(), msgEntity.getType(), msgContent);
    }

    @Override
    public void closeConnection(){
        synchronized (eventOutput) {
            if (!eventOutput.isClosed()) {
                try {
                    eventOutput.close();
                    logger.debug("SSE -- close connection, clientId: {}", getClientId());
                } catch (IOException ex) {
                    ex.printStackTrace();
                    logger.error("SSE -- close connection error, clientId: {}", getClientId());
                }
            }
        }
    }
}
